import { colorToRGBA, rad2deg } from "./index";

export function drawCircle(ctx, pos, radius, style, light) {
    if (light) {
        const lightStyle = Object.assign({
            color: "RGBA(255,255,255,1)",
            radius: 1,
            expand: 0
        }, light);

        const c = colorToRGBA(lightStyle.color);
        const grd = ctx.createRadialGradient(pos[0], pos[1], lightStyle.expand, pos[0], pos[1], lightStyle.radius);
        grd.addColorStop(0, c);
        const s = c.split(",");
        s[s.length - 1] = "0)";
        const endColor = s.join(",");
        grd.addColorStop(1, endColor);

        ctx.fillStyle = grd;
        ctx.beginPath();
        ctx.arc(pos[0], pos[1], lightStyle.radius, 0, Math.PI * 2);
        ctx.closePath();
        ctx.fill();
    }

    parseStyle(ctx, style);
    ctx.beginPath();
    ctx.arc(pos[0], pos[1], radius || 1, 0, Math.PI * 2);
    if (style && style.strokeStyle) {
        ctx.stroke();
    }
    ctx.closePath();
    ctx.fill();
}

const imgCaches = {};

export function drawImage(ctx, url, param, onDrawn) {
    param = Object.assign({
        pos: [0, 0],
        anchor: [0, 0],
        angle: 0,
        scale: 1
    }, param);

    let img = imgCaches[url];
    if (!img) {
        img = new MImage(url, param.width, param.height);
        img.onLoadedEvent = () => { img.draw(ctx); }
        img.src = url;
        Object.assign(img, param);
        img.onDrawn = onDrawn
        imgCaches[url] = img;
    } else {
        Object.assign(img, param);
        img.width = param.width || img.width;
        img.height = param.height || img.height;
        img.onDrawn = onDrawn
        img.draw(ctx);
    }

    return img;
}

class MImage extends Image {
    constructor(url = "", width, height) {
        super(width, height);
        this.src = url;
        this.pos = [0, 0];
        this.anchor = [0, 0];
        this.angle = 0;
        this.scale = 1;
        this.onLoadedEvent = null;
        this.inited = false;
        this.onload = () => {
            this.inited = true;
            this.onLoadedEvent && this.onLoadedEvent();
        }
        this.onDrawn = null;
        this.setAttribute('crossOrigin', 'anonymous');
    }

    draw(ctx) {
        if (!this.inited || !this.scale) { //缩放不能为0，防止除零错误
            return;
        }
        const that = this, s = that.scale, w = that.width, h = that.height;
        ctx.translate(this.pos[0], this.pos[1]);
        ctx.rotate(that.angle);
        ctx.scale(s, s);
        ctx.drawImage(that, - that.anchor[0] * w, -  that.anchor[1] * h, w, h);
        ctx.scale(1 / s, 1 / s);
        ctx.rotate(-that.angle);
        ctx.translate(-this.pos[0], -this.pos[1]);

        if (that.onDrawn) {
            that.onDrawn();
        }
    }
}

export function drawLine(ctx, points, style, lineStyle) {
    if (!points || points.length <= 0) {
        return;
    }

    if (typeof draw != "undefined") {
        draw = function () {

        };
    }

    parseStyle(ctx, style);
    if (lineStyle && lineStyle.dash) {
        ctx.setLineDash(lineStyle.dash);
    } else {
        ctx.setLineDash([]);
    }
    ctx.beginPath();
    let p = points[0];
    ctx.moveTo(p[0], p[1]);
    for (let i = 1; i < points.length; i++) {
        p = points[i];
        ctx.lineTo(p[0], p[1]);
    }
    if (lineStyle && lineStyle.close) {
        ctx.closePath();
    }
    ctx.stroke();
    if (style && style.fillStyle) {
        ctx.fill();
    }
}

function parseStyle(ctx, style) {
    for (const k in style) {
        ctx[k] = style[k];
    }
}

export function getImagePixel(dataArray, width, height) {
    const out = [[]];
    for (let i = 0, w = width, h = -1; i < dataArray.length && h < height; i += 4, w++) {
        if (w >= width) {
            w = 0;
            h++;
            out[h] = [];
        }
        out[h].push({
            r: dataArray[i],
            g: dataArray[i + 1],
            b: dataArray[i + 2],
            a: dataArray[i + 3],
        });
    }
    return out;
}

export function clear(ctx) {
    ctx.canvas.width = ctx.canvas.width;
}